package com.example.ref;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import com.example.ref.select.Where;
import com.example.ref.select.Where.OrderBy;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;


public class From<T> extends Statement implements Generic<T>
{
	private Select select;
	Class<T> innerClass;
	public List<OrderBy> orderBy;
	Field[] fields;
	
	public From(Select select,Class<T> _class)
	{
		this.select=select;
		this.innerClass=_class;
		
		builder.append("SELECT ");
		builder.append(select.what);
		builder.append(" FROM [");
		builder.append(_class.getName());
		builder.append("] ");
		
		fields=_class.getDeclaredFields();
	}
	/**
	 * Creates a Where statement
	 * @param field name of field of the class
	 * @param operator a constant from RSQLiteOperator class
	 * @param value string value
	 * @throws Exception if field is not found
	 */
	public Where<T> where(String field,int operator,Object value) throws Exception
	{
		return new Where<T>(this,field,operator,value);
	}
	
	public int count(Context context)
	{	
		return RSQLiteDatabaseHelper.count(innerClass,builder,context);
		
	}
	@Override
	public List<T> execute(Context context) throws Exception {
		return RSQLiteDatabaseHelper.select(null,this.innerClass, context,builder.toString(),null,getSelect().limit);
	}

	@Override
	public  List<T> execute(SQLiteDatabase database, Context context)
			throws Exception {
		return RSQLiteDatabaseHelper.select(database,this.innerClass, context,builder.toString(),null,getSelect().limit);
	}
	public  From<T> addOrderBy(String field, String orientation) throws Exception
	{
		RSQLiteDatabaseHelper.throwIfFieldDoesntExists(fields,field);

		if(orderBy==null)
			orderBy= new ArrayList<Where.OrderBy>();

		orderBy.add(new OrderBy(field, orientation));
		return this;
	}


	@Override
	public StringBuilder getBuilder() {
		return builder;
	}

	@Override
	public Class<T> getInnerClass() {
		return innerClass;
	}
	
	public Select getSelect() {
		return select;
	}


}
